#ifndef SF_CRYPTO_H
#define SF_CRYPTO_H

#include <glib.h>
#include <glib-object.h>

#define SF_CRYPTO_ERROR (sf_crypto_error_quark())
GQuark sf_crypto_error_quark(void);

extern const gchar *SF_CRYPTO_DEFAULT_PLUGIN;
extern const gchar *SF_CRYPTO_DEFAULT_STORAGE_PLUGIN;
extern const gchar *SF_CRYPTO_DEFAULT_CSPRNG_ENGINE;

typedef enum SfCryptoResult_ {
    SF_CRYPTO_RESULT_SUCCEEDED = 0,
    SF_CRYPTO_RESULT_PENDING = 1,
    SF_CRYPTO_RESULT_FAILED = 2
} SfCryptoResult;

typedef enum SfCryptoError_ {
    SF_CRYPTO_ERROR_NO = 0,
    SF_CRYPTO_ERROR_UNKNOWN = 2,
    SF_CRYPTO_ERROR_SERIALIZATION = 3,
    SF_CRYPTO_ERROR_STORAGE = 4,
    SF_CRYPTO_ERROR_DAEMON = 5,
    SF_CRYPTO_ERROR_DISCOVERY = 6,

    SF_CRYPTO_ERROR_INVALID_CRYPTOGRAPHIC_SERVICE_PROVIDER = 10,
    SF_CRYPTO_ERROR_INVALID_STORAGE_PROVIDER,
    SF_CRYPTO_ERROR_INVALID_KEY_IDENTIFIER,
    SF_CRYPTO_ERROR_DUPLICATE_KEY_IDENTIFIER,
    SF_CRYPTO_ERROR_CRYPTO_MANAGER_NOT_INITIALIZED,
    SF_CRYPTO_ERROR_INVALID_INITIALIZATION_VECTOR,
    SF_CRYPTO_ERROR_INVALID_AUTHENTICATION_TAG,

    SF_CRYPTO_ERROR_OPERATION_NOT_SUPPORTED = 20,
    SF_CRYPTO_ERROR_BLOCK_MODE_NOT_SUPPORTED,
    SF_CRYPTO_ERROR_ENCRYPTION_PADDING_NOT_SUPPORTED,
    SF_CRYPTO_ERROR_SIGNATURE_PADDING_NOT_SUPPORTED,
    SF_CRYPTO_ERROR_DIGEST_NOT_SUPPORTED,

    SF_CRYPTO_ERROR_EMPTY_SECRET_KEY = 30,
    SF_CRYPTO_ERROR_EMPTY_PRIVATE_KEY,
    SF_CRYPTO_ERROR_EMPTY_PUBLIC_KEY,
    SF_CRYPTO_ERROR_EMPTY_DATA,
    SF_CRYPTO_ERROR_EMPTY_SIGNATURE,

    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_ENCRYPTION = 40,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_DECRYPTION,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_RANDOM_DATA,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_CIPHER_SESSION,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_KEY_GENERATION,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_KEY_IMPORT,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_DIGEST,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_SIGNING,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_VERIFICATION,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_AUTHENTICATION_TAG,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_INVALID_CIPHER_SESSION_TOKEN,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_INCORRECT_PASSPHRASE,
    SF_CRYPTO_ERROR_CRYPTO_PLUGIN_IS_LOCKED,

    SF_CRYPTO_ERROR_NETWORK = 98,
    SF_CRYPTO_ERROR_NETWORK_SSL = 99,
    SF_CRYPTO_ERROR_HTTP_CONTINUE = 100,
    SF_CRYPTO_ERROR_HTTP_SWITCHING_PROTOCOL = 101,
    SF_CRYPTO_ERROR_HTTP_OK = 200,
    SF_CRYPTO_ERROR_HTTP_CREATED = 201,
    SF_CRYPTO_ERROR_HTTP_ACCEPTED = 202,
    SF_CRYPTO_ERROR_HTTP_NON_AUTHORITATIVE_INFORMATION = 203,
    SF_CRYPTO_ERROR_HTTP_NO_CONTENT = 204,
    SF_CRYPTO_ERROR_HTTP_RESET_CONTENT = 205,
    SF_CRYPTO_ERROR_HTTP_PARTIAL_CONTENT = 206,
    SF_CRYPTO_ERROR_HTTP_MULTIPLE_CHOICE = 300,
    SF_CRYPTO_ERROR_HTTP_MOVED_PERMANENTLY = 301,
    SF_CRYPTO_ERROR_HTTP_FOUND = 302,
    SF_CRYPTO_ERROR_HTTP_SEE_OTHER = 303,
    SF_CRYPTO_ERROR_HTTP_NOT_MODIFIED = 304,
    SF_CRYPTO_ERROR_HTTP_USE_PROXY = 305,
    SF_CRYPTO_ERROR_HTTP_UNUSED = 306,
    SF_CRYPTO_ERROR_HTTP_TEMPORARY_REDIRECT = 307,
    SF_CRYPTO_ERROR_HTTP_PERMANENT_REDIRECT = 308,
    SF_CRYPTO_ERROR_HTTP_BAD_REQUEST = 400,
    SF_CRYPTO_ERROR_HTTP_UNAUTHORIZED = 401,
    SF_CRYPTO_ERROR_HTTP_PAYMENT_REQUIRED = 402,
    SF_CRYPTO_ERROR_HTTP_FORBIDDEN = 403,
    SF_CRYPTO_ERROR_HTTP_NOT_FOUND = 404,
    SF_CRYPTO_ERROR_HTTP_METHOD_NOT_ALLOWED = 405,
    SF_CRYPTO_ERROR_HTTP_NOT_ACCEPTABLE = 406,
    SF_CRYPTO_ERROR_HTTP_PROXY_AUTHENTICATION_REQUIRED = 407,
    SF_CRYPTO_ERROR_HTTP_REQUEST_TIMEOUT = 408,
    SF_CRYPTO_ERROR_HTTP_CONFLICT = 409,
    SF_CRYPTO_ERROR_HTTP_GONE = 410,
    SF_CRYPTO_ERROR_HTTP_LENGTH_REQUIRED = 411,
    SF_CRYPTO_ERROR_HTTP_PRECONDITION_FAILED = 412,
    SF_CRYPTO_ERROR_HTTP_PAYLOAD_TOO_LARGE = 413,
    SF_CRYPTO_ERROR_HTTP_URI_TOO_LONG = 414,
    SF_CRYPTO_ERROR_HTTP_UNSUPPORTED_MEDIA_TYPE = 415,
    SF_CRYPTO_ERROR_HTTP_REQUEST_RANGE_NOT_SATISFIABLE = 416,
    SF_CRYPTO_ERROR_HTTP_EXPECTATION_FAILED = 417,
    SF_CRYPTO_ERROR_HTTP_MISDIRECTED_REQUEST = 421,
    SF_CRYPTO_ERROR_HTTP_UPGRADE_REQUIRED = 426,
    SF_CRYPTO_ERROR_HTTP_PRECONDITION_REQUIRED = 428,
    SF_CRYPTO_ERROR_HTTP_TOO_MANY_REQUESTS = 429,
    SF_CRYPTO_ERROR_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
    SF_CRYPTO_ERROR_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
    SF_CRYPTO_ERROR_HTTP_INTERNAL_SERVER = 500,
    SF_CRYPTO_ERROR_HTTP_NOT_IMPLEMENTED = 501,
    SF_CRYPTO_ERROR_HTTP_BAD_GATEWAY = 502,
    SF_CRYPTO_ERROR_HTTP_SERVICE_UNAVAILABLE = 503,
    SF_CRYPTO_ERROR_HTTP_GATEWAY_TIMEOUT = 504,
    SF_CRYPTO_ERROR_HTTP_VERSION_NOT_SUPPORTED = 505,
    SF_CRYPTO_ERROR_HTTP_VARIANT_ALSO_NEGOTIATES = 506,
    SF_CRYPTO_ERROR_HTTP_INSUFFICIENT_STORAGE = 507,
    SF_CRYPTO_ERROR_HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511,

    SF_CRYPTO_ERROR_OTHER = 1024,
} SfCryptoError;

typedef enum SfCryptoAlgorithm_ {
    SF_CRYPTO_ALGORITHM_UNKNOWN        = 0,
    SF_CRYPTO_ALGORITHM_CUSTOM         = 1,
SF_CRYPTO_ALGORITHM_ASYMMETRIC_FIRST    = 10,
    SF_CRYPTO_ALGORITHM_RSA            = 10,
    SF_CRYPTO_ALGORITHM_DSA            = 20,
    SF_CRYPTO_ALGORITHM_DH             = 30,
    SF_CRYPTO_ALGORITHM_EC             = 40,
    SF_CRYPTO_ALGORITHM_ECDSA,
    SF_CRYPTO_ALGORITHM_EDDSA,
    SF_CRYPTO_ALGORITHM_ECDH,
    SF_CRYPTO_ALGORITHM_ECMQV,
SF_CRYPTO_ALGORITHM_ASYMMETRIC_LAST     = 255,
SF_CRYPTO_ALGORITHM_SYMMETRIC_FIRST,
    SF_CRYPTO_ALGORITHM_AES            = 260,
    SF_CRYPTO_ALGORITHM_GOST           = 270,
    SF_CRYPTO_ALGORITHM_TDEA           = 280,
    SF_CRYPTO_ALGORITHM_TDES           = SF_CRYPTO_ALGORITHM_TDEA,
    SF_CRYPTO_ALGORITHM_BLOWFISH       = 290,
    SF_CRYPTO_ALGORITHM_SALSA          = 300,
    SF_CRYPTO_ALGORITHM_SALSA20        = SF_CRYPTO_ALGORITHM_SALSA,
    SF_CRYPTO_ALGORITHM_CHACHA         = 310,
    SF_CRYPTO_ALGORITHM_CHACHA20       = SF_CRYPTO_ALGORITHM_CHACHA,
    SF_CRYPTO_ALGORITHM_RC4            = 320,
    SF_CRYPTO_ALGORITHM_RC5            = 330,
    SF_CRYPTO_ALGORITHM_RC6            = 340,
    SF_CRYPTO_ALGORITHM_SQUARE         = 350,
    SF_CRYPTO_ALGORITHM_SERPENT        = 360,
    SF_CRYPTO_ALGORITHM_PANAMA         = 370,
SF_CRYPTO_ALGORITHM_SYMMETRIC_LAST = 4095,
SF_CRYPTO_ALGORITHM_LAST = SF_CRYPTO_ALGORITHM_SYMMETRIC_LAST
} SfCryptoAlgorithm;

typedef enum SfCryptoBlockMode_ {
        SF_CRYPTO_BLOCK_MODE_UNKNOWN    = 0,
        SF_CRYPTO_BLOCK_MODE_CUSTOM,
        SF_CRYPTO_BLOCK_MODE_ECB,
        SF_CRYPTO_BLOCK_MODE_CBC,
        SF_CRYPTO_BLOCK_MODE_PCBC,
        SF_CRYPTO_BLOCK_MODE_CFB1,
        SF_CRYPTO_BLOCK_MODE_CFB8,
        SF_CRYPTO_BLOCK_MODE_CFB128,
        SF_CRYPTO_BLOCK_MODE_OFB,
        SF_CRYPTO_BLOCK_MODE_CTR,
        SF_CRYPTO_BLOCK_MODE_GCM,
        SF_CRYPTO_BLOCK_MODE_LRW,
        SF_CRYPTO_BLOCK_MODE_XEX,
        SF_CRYPTO_BLOCK_MODE_XTS,
        SF_CRYPTO_BLOCK_MODE_CMC,
        SF_CRYPTO_BLOCK_MODE_EME,
        SF_CRYPTO_BLOCK_MODE_CCM,
        SF_CRYPTO_BLOCK_MODE_LAST       = 255 // reserve
} SfCryptoBlockMode;

typedef enum SfCryptoEncryptionPadding_ {
    SF_CRYPTO_ENCRYPTION_PADDING_UNKNOWN    = 0,
    SF_CRYPTO_ENCRYPTION_PADDING_CUSTOM,
    SF_CRYPTO_ENCRYPTION_PADDING_NONE,
    SF_CRYPTO_ENCRYPTION_PADDING_PKCS7,
    SF_CRYPTO_ENCRYPTION_PADDING_RSA_OAEP,
    SF_CRYPTO_ENCRYPTION_PADDING_RSA_OAEP_MGF1,
    SF_CRYPTO_ENCRYPTION_PADDING_RSA_PKCS1,
    SF_CRYPTO_ENCRYPTION_PADDING_ANSI_X923,
    SF_CRYPTO_ENCRYPTION_PADDING_LAST       = 255 // reserve
} SfCryptoEncryptionPadding;

typedef enum SfCryptoSignaturePadding_ {
    SF_CRYPTO_SIGNATURE_PADDING_UNKNOWN     = 0,
    SF_CRYPTO_SIGNATURE_PADDING_CUSTOM,
    SF_CRYPTO_SIGNATURE_PADDING_NONE,
    SF_CRYPTO_SIGNATURE_PADDING_RSA_PSS,
    SF_CRYPTO_SIGNATURE_PADDING_RSA_PKCS1    = SF_CRYPTO_ENCRYPTION_PADDING_RSA_PKCS1,
    SF_CRYPTO_SIGNATURE_PADDING_ANSI_X923    = SF_CRYPTO_ENCRYPTION_PADDING_ANSI_X923,
    SF_CRYPTO_SIGNATURE_PADDING_LAST        = 255 // reserve
} SfCryptoSignaturePadding;

typedef enum SfCryptoDigest_ {
    SF_CRYPTO_DIGEST_UNKNOWN       = 0,
    SF_CRYPTO_DIGEST_CUSTOM        = 1,
    SF_CRYPTO_DIGEST_MD5           = 5,
    SF_CRYPTO_DIGEST_SHA1          = 10,
    SF_CRYPTO_DIGEST_SHA2_224      = 20,
    SF_CRYPTO_DIGEST_SHA2_256      = 21,
    SF_CRYPTO_DIGEST_SHA256        = SF_CRYPTO_DIGEST_SHA2_256,
    SF_CRYPTO_DIGEST_SHA2_384      = 22,
    SF_CRYPTO_DIGEST_SHA2_512      = 23,
    SF_CRYPTO_DIGEST_SHA512        = SF_CRYPTO_DIGEST_SHA2_512,
    SF_CRYPTO_DIGEST_SHA2_512_224  = 24,
    SF_CRYPTO_DIGEST_SHA2_512_256  = 25,
    SF_CRYPTO_DIGEST_SHA3_224      = 30,
    SF_CRYPTO_DIGEST_SHA3_256,
    SF_CRYPTO_DIGEST_SHA3_384,
    SF_CRYPTO_DIGEST_SHA3_512,
    SF_CRYPTO_DIGEST_SHAKE128,
    SF_CRYPTO_DIGEST_SHAKE256,
    SF_CRYPTO_DIGEST_GOST_94       = 40,
    SF_CRYPTO_DIGEST_GOST_2012_256,
    SF_CRYPTO_DIGEST_GOST_2012_512,
    SF_CRYPTO_DIGEST_BLAKE         = 50,
    SF_CRYPTO_DIGEST_BLAKE2,
    SF_CRYPTO_DIGEST_BLAKE2b,
    SF_CRYPTO_DIGEST_BLAKE2s,
    SF_CRYPTO_DIGEST_WHIRLPOOL     = 60,
    SF_CRYPTO_DIGEST_RIPE_MD        = 70,
    SF_CRYPTO_DIGEST_RIPE_MD128_256,
    SF_CRYPTO_DIGEST_RIPE_MD160,
    SF_CRYPTO_DIGEST_RIPE_MD320,
    SF_CRYPTO_DIGEST_TIGER         = 80,
    SF_CRYPTO_DIGEST_TIGER128,
    SF_CRYPTO_DIGEST_TIGER160,
    SF_CRYPTO_DIGEST_TIGER192,
    SF_CRYPTO_DIGEST_TIGER2,
    SF_CRYPTO_DIGEST_TIGER2_128,
    SF_CRYPTO_DIGEST_TIGER2_160,
    SF_CRYPTO_DIGEST_TIGER2_192,
    SF_CRYPTO_DIGEST_RADIO_GATUN    = 90,
    SF_CRYPTO_DIGEST_FUNCTION_LAST  = 4095 // reserve
} SfCryptoDigest;

typedef enum SfCryptoMac_ {
        SF_CRYPTO_MAC_UNKNOWN          = 0,
        SF_CRYPTO_MAC_CUSTOM           = 1,
        SF_CRYPTO_MAC_HMAC             = 10,
        SF_CRYPTO_MAC_CMAC             = 20,
        SF_CRYPTO_MAC_VMAC             = 30,
        SF_CRYPTO_MAC_POLY1305         = 40,
        SF_CRYPTO_MAC_LAST             = 255 // reserve
} SfCryptoMac;

typedef enum SfCryptoKdf_ {
        SF_CRYPTO_KDF_UNKNOWN          = 0,
        SF_CRYPTO_KDF_CUSTOM           = 1,
        SF_CRYPTO_KDF_PKCS5_PBKDF2      = 10,
        SF_CRYPTO_KDF_HKDF             = 20,
        SF_CRYPTO_KDF_BCRYPT           = 30,
        SF_CRYPTO_KDF_SCRYPT           = 40,
        SF_CRYPTO_KDF_ARGON2           = 50,
        SF_CRYPTO_KDF_ARGON2d          = SF_CRYPTO_KDF_ARGON2,
        SF_CRYPTO_KDF_ARGON2i          = 51,
        SF_CRYPTO_KDF_ARGON2id         = 52,
        SF_CRYPTO_KDF_LYRA2            = 60,
        SF_CRYPTO_KDF_LAST             = 255 // reserve
} SfCryptoKdf;

typedef enum SfCryptoCurve {
        SF_CRYPTO_CURVE_UNKNOWN            = 0,

        // SECT curves
        SF_CRYPTO_CURVE_SECT163K1          = 10,
        SF_CRYPTO_CURVE_SECT163R1,
        SF_CRYPTO_CURVE_SECT163R2,
        SF_CRYPTO_CURVE_SECT193R1,
        SF_CRYPTO_CURVE_SECT193R2,
        SF_CRYPTO_CURVE_SECT233K1,
        SF_CRYPTO_CURVE_SECT233R1,
        SF_CRYPTO_CURVE_SECT239K1,
        SF_CRYPTO_CURVE_SECT283K1,
        SF_CRYPTO_CURVE_SECT283R1,
        SF_CRYPTO_CURVE_SECT409K1,
        SF_CRYPTO_CURVE_SECT409R1,
        SF_CRYPTO_CURVE_SECT571K1,
        SF_CRYPTO_CURVE_SECT571R1,

        // SECP curves
        SF_CRYPTO_CURVE_SECP160K1          = 50,
        SF_CRYPTO_CURVE_SECP160R1,
        SF_CRYPTO_CURVE_SECP160R2,
        SF_CRYPTO_CURVE_SECP192K1,
        SF_CRYPTO_CURVE_SECP192R1,
        SF_CRYPTO_CURVE_SECP224K1,
        SF_CRYPTO_CURVE_SECP224R1,
        SF_CRYPTO_CURVE_SECP256K1,
        SF_CRYPTO_CURVE_SECP256R1,
        SF_CRYPTO_CURVE_SECP384R1,
        SF_CRYPTO_CURVE_SECP521R1,

        // NIST curves
        SF_CRYPTO_CURVE_NIST_K163           = SF_CRYPTO_CURVE_SECT163K1,
        SF_CRYPTO_CURVE_NIST_B163           = SF_CRYPTO_CURVE_SECT163R2,
        SF_CRYPTO_CURVE_NIST_K233           = SF_CRYPTO_CURVE_SECT233K1,
        SF_CRYPTO_CURVE_NIST_B233           = SF_CRYPTO_CURVE_SECT233R1,
        SF_CRYPTO_CURVE_NIST_K283           = SF_CRYPTO_CURVE_SECT283K1,
        SF_CRYPTO_CURVE_NIST_B283           = SF_CRYPTO_CURVE_SECT283R1,
        SF_CRYPTO_CURVE_NIST_K409           = SF_CRYPTO_CURVE_SECT409K1,
        SF_CRYPTO_CURVE_NIST_B409           = SF_CRYPTO_CURVE_SECT409R1,
        SF_CRYPTO_CURVE_NIST_K571           = SF_CRYPTO_CURVE_SECT571K1,
        SF_CRYPTO_CURVE_NIST_B571           = SF_CRYPTO_CURVE_SECT571K1,
        SF_CRYPTO_CURVE_NIST_P192           = SF_CRYPTO_CURVE_SECP192R1,
        SF_CRYPTO_CURVE_NIST_P224           = SF_CRYPTO_CURVE_SECP224R1,
        SF_CRYPTO_CURVE_NIST_P256           = SF_CRYPTO_CURVE_SECP256R1,
        SF_CRYPTO_CURVE_NIST_P384           = SF_CRYPTO_CURVE_SECP384R1,
        SF_CRYPTO_CURVE_NIST_P521           = SF_CRYPTO_CURVE_SECP521R1,

        // ANSI X9.62 primary field curves
        SF_CRYPTO_CURVE_A_X962PRIME192V1    = SF_CRYPTO_CURVE_SECP192R1,
        SF_CRYPTO_CURVE_A_X962PRIME192V2    = 101,
        SF_CRYPTO_CURVE_A_X962PRIME192V3,
        SF_CRYPTO_CURVE_A_X962PRIME239V1,
        SF_CRYPTO_CURVE_A_X962PRIME239V2,
        SF_CRYPTO_CURVE_A_X962PRIME239V3,
        SF_CRYPTO_CURVE_A_X962PRIME256V1    = SF_CRYPTO_CURVE_SECP256R1,

        // ANSI X9.62 binary field curves
        SF_CRYPTO_CURVE_A_X962C2PNB163V1    = 150,
        SF_CRYPTO_CURVE_A_X962C2PNB163V2,
        SF_CRYPTO_CURVE_A_X962C2PNB163V3,
        SF_CRYPTO_CURVE_A_X962C2PNB176V1,
        SF_CRYPTO_CURVE_A_X962C2TNB191V1,
        SF_CRYPTO_CURVE_A_X962C2TNB191V2,
        SF_CRYPTO_CURVE_A_X962C2TNB191V3,
        SF_CRYPTO_CURVE_A_X962C2PNB208W1,
        SF_CRYPTO_CURVE_A_X962C2TNB239V1,
        SF_CRYPTO_CURVE_A_X962C2TNB239V2,
        SF_CRYPTO_CURVE_A_X962C2TNB239V3,
        SF_CRYPTO_CURVE_A_X962C2PNB272W1,
        SF_CRYPTO_CURVE_A_X962C2PNB304W1,
        SF_CRYPTO_CURVE_A_X962C2TNB359V1,
        SF_CRYPTO_CURVE_A_X962C2PNB368W1,
        SF_CRYPTO_CURVE_A_X962C2TNB431R1,

        // WTLS
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS1 = 200,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS2,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS3,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS4,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS5,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS6,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS7,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS8,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS9,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS10,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS11,
        SF_CRYPTO_CURVE_WAP_WSG_IDM_ECID_WTLS12,

        // Independent "special" curves
        SF_CRYPTO_CURVE25519          = 250,  // 128 bit security
        SF_CRYPTO_CURVE41417,
        SF_CRYPTO_CURVE1174,
        SF_CRYPTO_CURVE_M221,
        SF_CRYPTO_CURVE_E222,
        SF_CRYPTO_CURVE_E382,
        SF_CRYPTO_CURVE_M383,
        SF_CRYPTO_CURVE448,  // 224 bit security
        SF_CRYPTO_CURVE_ED448_GOLDILOCKS,
        SF_CRYPTO_CURVE_M511,
        SF_CRYPTO_CURVE_E521,

        // Brainpool "random" prime curves
        SF_CRYPTO_CURVE_BRAINPOOL_P160R1= 300,
        SF_CRYPTO_CURVE_BRAINPOOL_P160T1,
        SF_CRYPTO_CURVE_BRAINPOOL_P192R1,
        SF_CRYPTO_CURVE_BRAINPOOL_P192T1,
        SF_CRYPTO_CURVE_BRAINPOOL_P224R1,
        SF_CRYPTO_CURVE_BRAINPOOL_P224T1,
        SF_CRYPTO_CURVE_BRAINPOOL_P256R1,
        SF_CRYPTO_CURVE_BRAINPOOL_P256T1,
        SF_CRYPTO_CURVE_BRAINPOOL_P320R1,
        SF_CRYPTO_CURVE_BRAINPOOL_P320T1,
        SF_CRYPTO_CURVE_BRAINPOOL_P384R1,
        SF_CRYPTO_CURVE_BRAINPOOL_P384T1,
        SF_CRYPTO_CURVE_BRAINPOOL_P512R1,
        SF_CRYPTO_CURVE_BRAINPOOL_P512T1,

        SF_CRYPTO_CURVE_LAST           = 4096 // reserve
} SfCryptoCurve;

typedef enum SfCryptoOperation_ {
        SF_CRYPTO_OPERATION_UNKNOWN        = 0,
        SF_CRYPTO_OPERATION_CUSTOM         = 1,
        SF_CRYPTO_OPERATION_SIGN           = 2,
        SF_CRYPTO_OPERATION_VERIFY         = 4,
        SF_CRYPTO_OPERATION_ENCRYPT        = 8,
        SF_CRYPTO_OPERATION_DECRYPT        = 16,
        SF_CRYPTO_OPERATION_CALCULATE_DIGEST= 32,
        SF_CRYPTO_OPERATION_CALCULATE_MAC   = 64,
        SF_CRYPTO_OPERATION_DERIVE_KEY      = 128
} SfCryptoOperation;

typedef enum SfCryptoVerificationStatus_ {
        SF_CRYPTO_VERIFICATION_STATUS_UNKNOWN = 0,
        SF_CRYPTO_VERIFICATION_STATUS_SUCCEEDED = 1,
        SF_CRYPTO_VERIFICATION_STATUS_FAILED = 2,
        SF_CRYPTO_VERIFICATION_STATUS_SIGNATURE_INVALID = 4,
        SF_CRYPTO_VERIFICATION_STATUS_SIGNATURE_EXPIRED = 8,
        SF_CRYPTO_VERIFICATION_STATUS_KEY_EXPIRED = 16,
        SF_CRYPTO_VERIFICATION_STATUS_KEY_REVOKED = 32,
        SF_CRYPTO_VERIFICATION_STATUS_KEY_INVALID = 64
} SfCryptoVerificationStatus;

typedef enum SfCryptoEchoMode_ {
        SF_CRYPTO_ECHO_MODE_UNKNOWN = 0,
        SF_CRYPTO_ECHO_MODE_NORMAL,
        SF_CRYPTO_ECHO_MODE_PASSWORD,
        SF_CRYPTO_ECHO_MODE_NO,
} SfCryptoEchoMode;

typedef enum SfCryptoInputType_ {
    SF_CRYPTO_INPUT_TYPE_UNKNOWN        = 0,
    SF_CRYPTO_INPUT_TYPE_AUTHENTICATION = 1,  // returns non-empty data if the user authenticates via system dialog
    SF_CRYPTO_INPUT_TYPE_CONFIRMATION   = 2,  // returns non-empty data if the user allows the operation
    SF_CRYPTO_INPUT_TYPE_NUMERIC        = 4,  // returns the numeric (e.g. PIN) data from the user
    SF_CRYPTO_INPUT_TYPE_ALPHANUMERIC   = 8,  // returns the alphanumeric (e.g. passphrase) data from the user
    SF_CRYPTO_INPUT_TYPE_FINGERPRINT    = 16, // returns the fingerprint data from the user
    SF_CRYPTO_INPUT_TYPE_IRIS           = 32, // returns the iris data from the user
    SF_CRYPTO_INPUT_TYPE_RETINA         = 64, // returns the retina data from the user
    // reserved
    SF_CRYPTO_INPUT_TYPE_LAST           = 65536
} SfCryptoInputType;

typedef enum SfCryptoKeyPairType_ {
    SF_CRYPTO_KEY_PAIR_TYPE_UNKNOWN = SF_CRYPTO_ALGORITHM_UNKNOWN,
    SF_CRYPTO_KEY_PAIR_TYPE_CUSTOM = SF_CRYPTO_ALGORITHM_CUSTOM,
    SF_CRYPTO_KEY_PAIR_TYPE_RSA = SF_CRYPTO_ALGORITHM_RSA,
    SF_CRYPTO_KEY_PAIR_TYPE_DSA = SF_CRYPTO_ALGORITHM_DSA,
    SF_CRYPTO_KEY_PAIR_TYPE_DH = SF_CRYPTO_ALGORITHM_DH,
    SF_CRYPTO_KEY_PAIR_TYPE_EC = SF_CRYPTO_ALGORITHM_EC,
} SfCryptoKeyPairType;

typedef enum SfCryptoPluginState_ {
    SF_CRYPTO_PLUGIN_STATE_UNKNOWN   = 0,
    SF_CRYPTO_PLUGIN_STATE_AVAILABLE = 1 << 0,
    SF_CRYPTO_PLUGIN_STATE_MASTER_UNLOCKED = 1 << 1,
    SF_CRYPTO_PLUGIN_STATE_PLUGIN_UNLOCKED = 1 << 2,
    SF_CRYPTO_PLUGIN_STATE_PLUGIN_SUPPORTS_LOCKING = 1 << 3,
    SF_CRYPTO_PLUGIN_STATE_PLUGIN_SUPPORTS_SET_LOCK_CODE = 1 << 4,
} SfCryptoPluginState;

struct SfCryptoPluginInfo_ {
    gchar *display_name;
    gchar *name;
    int version;
    SfCryptoPluginState state;
};
typedef struct SfCryptoPluginInfo_ SfCryptoPluginInfo;

#define SF_TYPE_CRYPTO_PLUGIN_INFO sf_crypto_plugin_info_get_type()

GType sf_crypto_plugin_info_get_type(void);
void sf_crypto_plugin_info_free(SfCryptoPluginInfo *info);
SfCryptoPluginInfo *sf_crypto_plugin_info_copy(const SfCryptoPluginInfo *other);

#endif /* SF_CRYPTO_H */
